package TP5;

public class VectorEstado {

    private static double reloj;
    private Evento evento;
    //  Esta referencia debería apuntar a la misma lista que la del expendedor... supongo.
    private double rndTipoGaseosa;
    private double rndSeVa;
    private double rndLlegadaCliente;
    private double rndFinAtencionCliente;
    private double finAtencion;
    private double rndGaseosaAlternativa;
    private double rndRomperEmpates;
    private double tiempoEntreLlegadasCliente;
    private double proximaLlegadaCliente;
    private Expendedor expendedor;
    private double rndLlegadaRepositor;
    private double tiempoEntreLlegadasRepositor;
    private double proximaLlegadaRepositor;
    private EstadoRepositor estadoRepositor;
    private double finReposicion;
    private int contadorDeCambiosC;
    private int contadorDeCambiosA;
    private int contadorDeCambiosB;
    private int contadorDeReposiciones;
    private int contadorPersonasSalieronCola;
    private int contadorPersonasNoConsiguieronGaseosaDeseada;
    private int contadorPersonasNoConsiguieronGaseosaYseFueron;
    private int tamanoColaClientes;
    private tipoGaseosa gaseosaAlternativa;
    private tipoGaseosa gaseosaElejida;

    public void setGaseosaAlternativa(tipoGaseosa gaseosaAlternativa) {
        this.gaseosaAlternativa = gaseosaAlternativa;
    }

    public void setGaseosaElegida(tipoGaseosa gaseosaElejida) {
        this.gaseosaElejida = gaseosaElejida;
    }

    public Expendedor getExpendedor() {
        return expendedor;
    }

    public VectorEstado(VectorEstado actual) {
        rndFinAtencionCliente = 1;
        rndGaseosaAlternativa = 1;
        rndLlegadaCliente = 1;
        rndLlegadaRepositor = 1;
        rndRomperEmpates = 1;
        rndSeVa = 1;
        rndTipoGaseosa = 1;

        finAtencion = actual.getFinAtencion();
        finReposicion = actual.getFinReposicion();
        proximaLlegadaCliente = actual.getProximaLlegadaCliente();
        proximaLlegadaRepositor = actual.getProximaLlegadaRepositor();
        estadoRepositor = actual.estadoRepositor;
        tamanoColaClientes = actual.tamanoColaClientes;
        tiempoEntreLlegadasCliente = actual.tiempoEntreLlegadasCliente;
        tiempoEntreLlegadasRepositor = actual.tiempoEntreLlegadasRepositor;
        expendedor = new Expendedor(actual.getExpendedor());

        contadorDeCambiosA = actual.getContadorDeCambiosA();
        contadorDeCambiosB = actual.getContadorDeCambiosB();
        contadorDeCambiosC = actual.getContadorDeCambiosC();
        contadorDeReposiciones = actual.getContadorDeReposiciones();
        contadorPersonasNoConsiguieronGaseosaDeseada = actual.getContadorPersonasNoConsiguieronGaseosaDeseada();
        contadorPersonasNoConsiguieronGaseosaYseFueron = actual.getContadorPersonasNoConsiguieronGaseosaYseFueron();
        contadorPersonasSalieronCola = actual.getContadorPersonasSalieronCola();

    }

//    public void iniciarVector() {
//        rndFinAtencionCliente = 1;
//        rndGaseosaAlternativa = 1;
//        rndLlegadaCliente = 1;
//        rndLlegadaRepositor = 1;
//        rndRomperEmpates = 1;
//        rndSeVa = 1;
//        rndTipoGaseosa = 1;
//
//    }

    public VectorEstado(Expendedor expendedor) {
        this.expendedor = expendedor;
        evento = Evento.INICIAL;
        establecerEstadoRepositor();
        evento.calcularProximaLlegada(this);

    }

    public VectorEstado(int gaseosasA, int gaseosasB, int gaseosasC, int capacidad) {
        expendedor = new Expendedor(gaseosasA, gaseosasB, gaseosasC, capacidad);
    }

    public int getTamanoColaClientes() {
        return tamanoColaClientes;
    }

    public void setTamanoColaClientes(int tamanoColaClientes) {
        this.tamanoColaClientes = tamanoColaClientes;
    }

    public double getRndFinAtencionCliente() {
        return rndFinAtencionCliente;
    }

    public void setRndFinAtencionCliente() {
        this.rndFinAtencionCliente = Math.random();
    }

    public double getFinAtencion() {
        return finAtencion;
    }

    public void setFinAtencion(double finAtencion) {
        this.finAtencion = finAtencion;
    }

    public double getRndGaseosaAlternativa() {
        return rndGaseosaAlternativa;
    }

    public void setRndGaseosaAlternativa() {
        this.rndGaseosaAlternativa = Math.random();;
    }

    public double getRndRomperEmpates() {
        return rndRomperEmpates;
    }

    public void setRndRomperEmpates() {
        this.rndRomperEmpates = Math.random();
    }

    public double getTiempoEntreLlegadasCliente() {
        return tiempoEntreLlegadasCliente;
    }

    public void setTiempoEntreLlegadasCliente(double tiempoEntreLlegadasCliente) {
        this.tiempoEntreLlegadasCliente = tiempoEntreLlegadasCliente;
    }

    public double getProximaLlegadaCliente() {
        return proximaLlegadaCliente;
    }

    public void setProximaLlegadaCliente(double proximaLlegadaCliente) {
        this.proximaLlegadaCliente = proximaLlegadaCliente;
    }

    public double getTiempoEntreLlegadasRepositor() {
        return tiempoEntreLlegadasRepositor;
    }

    public void setTiempoEntreLlegadasRepositor(double tiempoEntreLlegadasRepositor) {
        this.tiempoEntreLlegadasRepositor = tiempoEntreLlegadasRepositor;
    }

    public double getProximaLlegadaRepositor() {
        return proximaLlegadaRepositor;
    }

    public void setProximaLlegadaRepositor(double proximaLlegadaRepositor) {
        this.proximaLlegadaRepositor = proximaLlegadaRepositor;
    }

    public EstadoRepositor getEstadoRepositor() {
        return estadoRepositor;
    }

    public void setEstadoRepositor(EstadoRepositor estadoRepositor) {
        this.estadoRepositor = estadoRepositor;
    }

    public double getFinReposicion() {
        return finReposicion;
    }

    public void setFinReposicion(double finReposicion) {
        this.finReposicion = finReposicion;
    }

    public int getContadorDeCambiosC() {
        return contadorDeCambiosC;
    }

    public void setContadorDeCambiosC(int contadorDeCambiosC) {
        this.contadorDeCambiosC = contadorDeCambiosC;
    }

    public int getContadorDeCambiosA() {
        return contadorDeCambiosA;
    }

    public void setContadorDeCambiosA(int contadorDeCambiosA) {
        this.contadorDeCambiosA = contadorDeCambiosA;
    }

    public int getContadorDeCambiosB() {
        return contadorDeCambiosB;
    }

    public void setContadorDeCambiosB(int contadorDeCambiosB) {
        this.contadorDeCambiosB = contadorDeCambiosB;
    }

    public int getContadorDeReposiciones() {
        return contadorDeReposiciones;
    }

    public void setContadorDeReposiciones(int contadorDeReposiciones) {
        this.contadorDeReposiciones = contadorDeReposiciones;
    }

    public int getContadorPersonasSalieronCola() {
        return contadorPersonasSalieronCola;
    }

    public void setContadorPersonasSalieronCola(int contadorPersonasSalieronCola) {
        this.contadorPersonasSalieronCola = contadorPersonasSalieronCola;
    }

    public int getContadorPersonasNoConsiguieronGaseosaDeseada() {
        return contadorPersonasNoConsiguieronGaseosaDeseada;
    }

    public void setContadorPersonasNoConsiguieronGaseosaDeseada(int contadorPersonasNoConsiguieronGaseosaDeseada) {
        this.contadorPersonasNoConsiguieronGaseosaDeseada = contadorPersonasNoConsiguieronGaseosaDeseada;
    }

    public int getContadorPersonasNoConsiguieronGaseosaYseFueron() {
        return contadorPersonasNoConsiguieronGaseosaYseFueron;
    }

    public void setContadorPersonasNoConsiguieronGaseosaYseFueron(int contadorPersonasNoConsiguieronGaseosaYseFueron) {
        this.contadorPersonasNoConsiguieronGaseosaYseFueron = contadorPersonasNoConsiguieronGaseosaYseFueron;
    }

    public double getReloj() {
        return reloj;
    }

    public void setReloj(double reloj) {
        this.reloj = reloj;
    }

    public Evento getEvento() {
        return evento;
    }

    public void setEvento(Evento evento) {
        this.evento = evento;
    }

    public double getRndTipoGaseosa() {
        return rndTipoGaseosa;
    }

    public void setRndTipoGaseosa() {
        this.rndTipoGaseosa = Math.random();
    }

    public double getRndSeVa() {
        return rndSeVa;
    }

    public void setRndSeVa() {
        this.rndSeVa = Math.random();
    }

    public double getRndLlegadaCliente() {
        return rndLlegadaCliente;
    }

    public void setRndLlegadaCliente() {
        this.rndLlegadaCliente = Math.random();
    }

    public double getRndLlegadaRepositor() {
        return rndLlegadaRepositor;
    }

    public void setRndLlegadaRepositor() {
        this.rndLlegadaRepositor = Math.random();
    }

    public void setExpendedor(Expendedor ex) {
        expendedor = ex;
    }

    private void establecerEstadoRepositor() {
        if (expendedor.getEstado() == EstadoServidor.OCUPADO_POR_CLIENTE) {
            estadoRepositor = EstadoRepositor.ESPERANDO;
        } else if (expendedor.getEstado() == EstadoServidor.LIBRE) {
            estadoRepositor = EstadoRepositor.REPONIENDO;
        }
    }

    public tipoGaseosa getGaseosaElegida() {
        if (rndTipoGaseosa < 0.55) {
            gaseosaElejida = tipoGaseosa.GaseosaA;


        }
        if (rndTipoGaseosa >= 0.55 && rndTipoGaseosa < 0.90) {
            gaseosaElejida = tipoGaseosa.GaseosaB;

        }
        if (rndTipoGaseosa >= 0.90) {
            gaseosaElejida = tipoGaseosa.GaseosaC;
        }

        return gaseosaElejida;


    }

    public boolean getSiSeVa() {
        if (rndSeVa > 0.5) {
            return true;
        }
        return false;
    }

    public tipoGaseosa getGaseosaAlternativa() {
        switch (gaseosaElejida) {
            case GaseosaA:
                if (rndGaseosaAlternativa > 0.5) {
                    gaseosaAlternativa = tipoGaseosa.GaseosaB;
                } else {
                    gaseosaAlternativa = tipoGaseosa.GaseosaC;
                }

                break;

            case GaseosaB:
                if (rndGaseosaAlternativa > 0.5) {
                    gaseosaAlternativa = tipoGaseosa.GaseosaC;
                } else {
                    gaseosaAlternativa = tipoGaseosa.GaseosaA;
                }
                break;

            case GaseosaC:
                if (rndGaseosaAlternativa > 0.5) {
                    gaseosaAlternativa = tipoGaseosa.GaseosaA;
                } else {
                    gaseosaAlternativa = tipoGaseosa.GaseosaB;
                }
                break;


            default:
                gaseosaAlternativa = tipoGaseosa.xxx;
        }
        return gaseosaAlternativa;

    }

    String getEmpateStock() {
        return " no implementado todavia el metodo";
    }

    double getRelojEventoProximo() {
        double min = this.getFinAtencion() + this.getFinReposicion();

        if (this.getFinAtencion() < min && this.getFinAtencion() > this.getReloj()) {
            min = this.getFinAtencion();
        }
        if (this.getFinReposicion() < min && this.getFinReposicion() > this.getReloj()) {
            min = this.getFinReposicion();
        }
        if (this.getProximaLlegadaCliente() < min && this.getProximaLlegadaCliente() > this.getReloj()) {
            min = this.getProximaLlegadaCliente();
        }
        if (this.getProximaLlegadaRepositor() < min && this.getProximaLlegadaRepositor() > this.getReloj()) {
            min = this.getProximaLlegadaRepositor();
        }
        return min;
    }

    public Evento getSiguienteEvento() {



        Evento siguiente = Evento.FIN_ATENCION_CLIENTE;
        double relojEvento = this.getFinAtencion();

        if (relojEvento == this.getReloj()) {
            siguiente = Evento.FIN_REPOSICION;
            relojEvento = this.getFinReposicion();
        }
        if (this.getFinReposicion() < relojEvento) {
            relojEvento = this.getFinReposicion();
            siguiente = Evento.FIN_REPOSICION;
        }
        if (this.getProximaLlegadaCliente() < relojEvento) {
            relojEvento = this.getProximaLlegadaCliente();
            siguiente = Evento.LLEGADA_CLIENTE;
        }
        if (this.getProximaLlegadaRepositor() < relojEvento) {
            relojEvento = this.getProximaLlegadaRepositor();
            siguiente = Evento.LLEGADA_REPOSITOR;
        }
        return siguiente;
    }

    public enum tipoGaseosa {

        GaseosaA, GaseosaB, GaseosaC, xxx
    }
}